/**
 * 重置当前节点样式
 * @param el: HTMLElement，传入当前绑定的input元素
 */
const resetError = (el) => {
  el.className = el.className.replace("err_class", "").trim();
  if (el.parentNode) {
    const ErrorNode = el.parentNode.querySelector(".err_message");
    if (ErrorNode) {
      el.parentNode.removeChild(ErrorNode);
    }
  }
};

/**
 * 执行错误提示函数，用err_class类名和含有错误信息的p元素表示未通过校验
 * @param el: HTMLElement，传入当前绑定的input元素
 * @param errorMsg: string，传入错误提示信息
 */
const validateError = (el, errorMsg) => {
  if (Array.prototype.includes.call(el.classList, "err_class")) {
    //如果当前组件里已经有了错误提示信息，什么也不做
    return;
  } else {
    const errorNode = document.createElement("p");
    errorNode.className = "err_message";
    errorNode.textContent = errorMsg;
    if (el.parentNode) {
      // 在当前input 元素后追加一个p元素，内容为错误提示
      el.parentNode.appendChild(errorNode);
    }
    // 在当前input 元素上添加一个err_class类名
    el.className += " err_class";
  }
};

const validate = {
  inserted: function(el, binding, vNode) {
    el.classList.add("v-check");
    el.addEventListener("blur", function(event) {
      resetError(el);
      // binding.value是传入自定义指令的参数，以数组的形式
      // 获取自定义指令中传入的校验规则参数和表单输入的值
      for (const rule of binding.value) {
        // 分别获取到自己定义的校验规则并执行
        const { message, type } = rule;
        const length = el.value.length;
        const value = el.value;
        if (type === "require" && !value) {
          // 如果必填
          validateError(el, message);
          break;
        }
        if (type === "noSpace" && el.value.includes(" ")) {
          // 如果不需要空格
          validateError(el, message);
          break;
        }
        if (type === "min" && length < rule.min) {
          // 最小长度
          validateError(el, message);
          break;
        }
        if (type === "max" && length > rule.max) {
          // 最大长度
          validateError(el, message);
          break;
        }
        if (type === "pattern" && !rule.pattern.test(el.value)) {
          // 正则校验
          validateError(el, message);
          break;
        }
        if (rule && typeof rule === "function") {
          // 自定义方法
          rule(vNode.context, el.value, validateError, el);
          break;
        }
      }
    });
  },
};

export default validate;
